home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
101_01
/
xword.c
< prev
next >
Wrap
Text File
|
1985-11-13
|
15KB
|
532 lines
/**********************************************************
*** ***
*** Copyright (c) 1981 by David M. Fogg ***
*** ***
*** 2632 N.E. Fremont ***
*** Portland, OR 97212 ***
*** ***
*** (503) 288-3502{HM} || 223-8033{WK} ***
*** ***
*** Permission is herewith granted for non- ***
*** commercial distribution through the BDS C ***
*** User's Group; any and all forms of commercial ***
*** redistribution are strenuously unwished-for. ***
*** ***
**********************************************************/
/* ---> XWORD.C <--- : Crossword Puzzle Program : Z-19 version
(C) Copyright 1980 by David M. Fogg @ New Day Computing - Portland, OR
9 APR 80 - 1st pass
25 oct 80: convert to BDS C 1st pass
26 Oct: add final touches
28 Oct: convert to VG MT
29 Oct: chg to oclose() in WRITS:
31 Oct: fix VG shift arrow prob;
add dubchk() to READS: & WRITS:;
chg putadv(..) 2 only move 2 nxt legal loc
4 Nov: convert back to Z-19/DMF environment
25 Nov: re-comp w/coin() as BIOS, not BDOS, call (1.4X comp);
make clue display automagickall
27 Nov: fix ERASE & READS to disp clues after scrn regen
3 Dec: chg dubchk() 2 wrk w/ lc 'y'; add scrn regen func;
improve getext() & reloc query.
* HINTS: answer files are FILNAM.ANS
* ANSER array
* <1st ACROSS clue
* rest of ACROSS clues
* <1st DOWN clue
* rest of DOWN clues
* EOF
* Partially filled-out screens are FILNAM.EXT
* (user specifies EXT)
* SCREEN array current contents
*
* All commands are single locase alfa chars;
* ucase alfa are put on screen @ curr position,
* & cursor is moved ACROSS or DOWN (current mode).
*
* Any letters put on screen by cheating
* ('peek' or 'giveup') are put in locase.
*/
#include <std.h>
#define MAXIZ 21 /* maximum rows/cols in puzzle */
#define AVLEN 35 /* avg clue length */
#define MAXLEN 65 /* max " " */
#define MXCLUES MAXIZ*MAXIZ/2 /* max # ACROSS+DOWN clues */
#define CLUBS MXCLUES*AVLEN /* size of clubuf[] */
#define DX 3 /* horiz dist btwn chars */
#define DY 1 /* vert " " " */
#define XORG 1 /* scrn X-ord of upleft char */
#define YORG 0 /* " Y-ord " " " */
/*
---> command characters <---
*/
#define ACROSS 'p' /* set mode to ACROSS */
#define DOWN 'q' /* " " " DOWN */
#define GOBAK '4' /* command to move cursor left */
#define GOFWD '6' /* " " " " right */
#define GOUP '8' /* " " " " up */
#define GODN '2' /* " " " " down */
#define TOPLN 't' /* goto top line in col */
#define BOTLN 'v' /* " bott " " " */
#define INITC 's' /* " init col " line */
#define FINC 'w' /* " final " " " */
#define PEEK '7' /* put anser letter on scrn */
#define UNDO '9' /* erase a single letter */
#define ERASE '3' /*** erase screen ***/
#define GIVUP '1' /*** fill in whole screen ***/
#define WRITS 'u' /* write scrn to file */
#define READS 'r' /* read " from " */
#define REGEN '\t' /* regenerate screen */
#define QUIT '5' /*** quit: exit program ***/
/*
---> misc ASCII &c <---
*/
#define MT '.' /* empty cell on screen */
#define WALL ' ' /* wall cell */
#define DELIM '<' /* delimit anser<ACROSS<DOWN in file */
#define RUBIT 0 /* erase scrn arg to scrini() */
#define RENUIT -1 /* regen scrn arg to scrini() */
/*
---> screen positions <---
*/
#define ACY 22 /* ACROSS clue line */
#define DCY 23 /* DOWN " " */
#define AHX 0 /* ACROSS hdr column */
#define DHX 2 /* DOWN " " */
#define ACX 8 /* ACROSS clue " */
#define DCX 8 /* DOWN " " */
#define FNY 0 /* filename line */
#define FNX 68 /* " column */
#define PRX 66 /* extension prompt col */
#define PRY 20 /* " " line */
#define INX 65 /* Instructions column */
#define INY 3 /* first Instructions line */
#define L25X 5 /* funkey ID line X-ord */
#define L25Y 24 /* " " " Y-ord */
/*
* * * * * * G L O B A L S * * * * * *
*/
char iobuf[BUFSIZ]; /* file I/O buffer */
int rows, cols; /* rows/cols in curr puzzle */
int crow, ccol; /* current (cursor) row/column */
int nacc, ndown; /* # of ACROSS/DOWN clues */
char scrn[MAXIZ][MAXIZ]; /* screen array */
char anser[MAXIZ][MAXIZ]; /* answer array */
char *aclu[MAXIZ][MAXIZ]; /* pointo ACROSS clues in clubuf */
char *dclu[MAXIZ][MAXIZ]; /* " DOWN " " " */
char clubuf[CLUBS]; /* clues buffer */
/* >>>-------------> M A I N P R O G R A M <-------------<<< */
main (ac, av)
int ac;
char *av[];
{
char filnam[12], ansfil[15]; /* file names */
int ansfd, scrfd; /* file descriptors */
char inch; /* input char from kbd */
int savr, savc; /* save crow,ccol */
char dir; /* direction/clue flag: a/d */
int arow, acol, drow, dcol; /* last ACROSS/DOWN clue cursor lox */
BOOL errms;
rows = cols = crow = ccol = nacc = ndown = 0;
arow = acol = drow = dcol = -1;
errms = NO;
if ((++av, --ac) != 1)
errxit("usage: xword ansfilnam");
strcpy(filnam, *av); strcpy(ansfil, *av);
strcat(ansfil, ".ANS");
if ((ansfd = fopen(ansfil, iobuf)) == ERROR)
errxit(".ANS file not found");
getans(); /* read .ANS file & setup clue pointers */
dir = scrini(filnam, NO); /* initialize screen */
/*
>>------> MAIN LOOP <------<<
*/
FOREVER {
cluput(arow, acol, drow, dcol);
arow = drow = crow;
acol = dcol = ccol;
inch = zchar();
if (errms) {
ereol(PRX, PRY);
errms = NO;
}
if (isupper(inch))
putadv(inch, dir);
else
switch (inch) {
case ACROSS: /* set dir (& print clue) */
toxy(AHX, ACY); puts("ACROSS:");
msgat(DHX, DCY, "DOWN:");
dir = ACROSS;
break;
case DOWN:
toxy(DHX, DCY); puts("DOWN:");
msgat(AHX, ACY, "ACROSS:");
dir = DOWN;
break;
case GOBAK: /* move one space left */
while (torc(crow, --ccol) == WALL);
break;
case GOFWD: /* move one space right */
while (torc(crow, ++ccol) == WALL);
break;
case GODN: /* move one space down */
while (torc(++crow, ccol) == WALL);
break;
case GOUP: /* move one space up */
while (torc(--crow, ccol) == WALL);
break;
case TOPLN: /* move to limit u/d/l/r */
case BOTLN:
case INITC:
case FINC:
crow = (inch == TOPLN) ? 0 : (inch == BOTLN) ? rows - 1: crow;
ccol = (inch == INITC) ? 0 : (inch == FINC) ? cols - 1 : ccol;
while (torc(crow, ccol) == WALL) {
crow += (inch == TOPLN) - (inch == BOTLN);
ccol += (inch == INITC) - (inch == FINC);
}
break;
case PEEK: /* peek: put anser ltr up */
putadv(tolower(anser[crow][ccol]), dir);
break;
case UNDO: /* erase a single letter */
putadv(MT, dir);
break;
case ERASE: /* erase screen */
if (dubchk()) {
dir = scrini(filnam, RUBIT);
acol = dcol = arow = drow = -1;
}
break;
case GIVUP: /* giveup: fillin screen */
savr = crow; savc = ccol;
if (dubchk()) {
for (crow = 0; crow < rows; ++crow)
for (ccol = 0; ccol < cols; ++ccol)
if (scrn[crow][ccol] == MT)
charon(scrn[crow][ccol] = tolower(anser[crow][ccol]));
}
torc(savr, savc);
break;
case WRITS: /* write screen to file */
savr = crow; savc = ccol;
if (dubchk())
if ((scrfd = getext(filnam, WRITE)) < 0) {
msgat(PRX, PRY, "FILE ERR");
errms = YES;
}
else {
for (crow = 0; crow < rows; ++crow) {
for (ccol = 0; ccol < cols; ++ccol)
putc(scrn[crow][ccol], iobuf);
fputs("\r\n", iobuf);
}
oclose(iobuf);
ereol(PRX, PRY);
}
torc(savr, savc);
break;
case READS: /* read screen fro